﻿using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using FU.Capstones.IMS.Web.Common;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.DataContracts;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.EventArgs;
using FU.Capstones.IMS.Web.Silverlight.Models;
using Microsoft.Practices.Prism.Commands;
using Navigation.Silverlight;

namespace FU.Capstones.IMS.Web.Silverlight.ViewModels
{
    public class WarehouseDetailViewModel : ViewModelBase
    {
        public WarehouseDetailViewModel()
        {
            Model = new WarehouseDetailModel();
            ((WarehouseDetailModel)Model).GetSingleWarehouseCompleted += DoGetSingleWarehouseCompleted;
            ((WarehouseDetailModel)Model).InsertWarehouseCompleted += DoInsertWarehouseCompleted;
            ((WarehouseDetailModel)Model).UpdateWarehouseCompleted += DoUpdateWarehouseCompleted;
            ((WarehouseDetailModel)Model).GetEmployeeCollectionCompleted += DoGetEmployeeCollectionCompleted;


            IsFirstLoaded = false;
            ServiceCallCounter += ((WarehouseDetailModel)Model).GetEmployeeCollectionAsync();

            MessageVisibility = Visibility.Collapsed;
            ErrorMessageVisibility = Visibility.Collapsed;

            CanEditOrAdd = CurrentUser.CanEditWarehouse || CurrentUser.CanAddWarehouse;
            CanAdd = CurrentUser.CanAddWarehouse;
        }

        #region Do Completed Methods

        void DoGetEmployeeCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Employee> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    EmployeeCollection = e.Result.Data;
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoUpdateWarehouseCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    Backup();   
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoInsertWarehouseCompleted(object sender, SingleFeedbackCompletedEventArgs<int> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    isCreateNew = false;
                    Warehouse.WarehouseID = e.Result.Data;
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetSingleWarehouseCompleted(object sender, SingleFeedbackCompletedEventArgs<Warehouse> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    //Asign the data from database
                    Warehouse = new Warehouse()
                    {
                        Address = e.Result.Data.Address,
                        Description = e.Result.Data.Description,
                        WarehouseID = e.Result.Data.WarehouseID,
                        WarehouseName = e.Result.Data.WarehouseName,
                        OfficePhone = e.Result.Data.OfficePhone,
                        Manager = e.Result.Data.Manager,
                        MaterialCollection = e.Result.Data.MaterialCollection,
                        ProductCollection = e.Result.Data.ProductCollection
                    };
                    if (Warehouse.MaterialCollection != null)
                    {
                        MaterialCollection = new PagedCollectionView(Warehouse.MaterialCollection);
                    }
                    if (Warehouse.ProductCollection != null)
                    {
                        ProductCollection = new PagedCollectionView(Warehouse.ProductCollection);
                    }
                    Backup();

                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        #endregion

        #region Commands

        private DelegateCommand<Warehouse> viewOrderCommand;
        public DelegateCommand<Warehouse> ViewOrderCommand
        {
            get
            {
                if (viewOrderCommand == null)
                    viewOrderCommand = new DelegateCommand<Warehouse>(DoViewOrderCommand);
                return viewOrderCommand;
            }
        }
        private DelegateCommand<Warehouse> viewProductCommand;
        public DelegateCommand<Warehouse> ViewProductCommand
        {
            get
            {
                if (viewProductCommand == null)
                    viewProductCommand = new DelegateCommand<Warehouse>(DoViewProductCommand);
                return viewProductCommand;
            }
        }
        private DelegateCommand<object> saveCommand;
        public DelegateCommand<object> SaveCommand
        {
            get
            {
                if (saveCommand == null)
                    saveCommand = new DelegateCommand<object>(DoSaveCommand);
                return saveCommand;
            }
        }
        private DelegateCommand<object> cancelCommand;
        public DelegateCommand<object> CancelCommand
        {
            get
            {
                if (cancelCommand == null)
                    cancelCommand = new DelegateCommand<object>(DoCancelCommand);
                return cancelCommand;
            }
        }
        private DelegateCommand<object> resetCommand;
        public DelegateCommand<object> ResetCommand
        {
            get
            {
                if (resetCommand == null)
                    resetCommand = new DelegateCommand<object>(DoResetCommand);
                return resetCommand;
            }
        }

        #endregion

        #region Do Command Methods

        private void DoViewOrderCommand(Warehouse obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.ProductOrderList, obj.WarehouseID);
        }

        private void DoViewProductCommand(Warehouse obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.ProductList, obj.WarehouseID);
        }

        private void DoResetCommand(object obj)
        {
            if (isCreateNew)
                Warehouse = new Warehouse();
            else
            {
                Warehouse = warehouseTemp;
                MappWithCollection();
                Backup();
            }
        }
        
        private void DoCancelCommand(object obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.WarehouseList);
        }

        private void DoSaveCommand(object obj)
        {
            Warehouse.ValidateAll();
            if (!Warehouse.HasErrors)
            {
                if (isCreateNew)
                {
                    ServiceCallCounter += ((WarehouseDetailModel)Model).InsertWarehouseAsync(Warehouse);
                }
                else
                {
                    ServiceCallCounter += ((WarehouseDetailModel)Model).UpdateWarehouseAsync(Warehouse);
                }
            }
        }

        #endregion

        #region Implementation of INavigationAware

        public override void OnNavigate(object extraData)
        {
            NavigationData data = (NavigationData) extraData;
            if (data != null)
            {
                if (string.Compare(data.NavigationUri, WebConstants.NavigationPages.WarehouseList) == 0)
                {
                    int? wID = (int?) data.Data;
                    isCreateNew =  !wID.HasValue || wID.Value == 0;
                    if (!isCreateNew)
                    {
                        IsFirstLoaded = true;
                        ServiceCallCounter += ((WarehouseDetailModel)Model).GetSingleWarehouseAsync(wID.Value);
                    }
                    else
                    {
                        Warehouse = new Warehouse();
                    }
                    Message = "Đang kết nối tới máy chủ...";
                }
            }
            else
            {
                Message = "Không hợp lệ.";
                ServiceCallCounter = 1;
            }
        }

        public override void OnLeave()
        {
            //throw new NotImplementedException();
        }

        #endregion

        #region Binding Properties

        private Warehouse warehouse;
        public Warehouse Warehouse
        {
            get { return warehouse; }
            set
            {
                if (!ReferenceEquals(warehouse, value))
                {
                    warehouse = value;
                    RaisePropertyChanged(() => Warehouse);
                }
            }
        }

        private ObservableCollection<Employee> employeeCollection;
        public ObservableCollection<Employee> EmployeeCollection
        {
            get { return employeeCollection; }
            set
            {
                if (!ReferenceEquals(employeeCollection, value))
                {
                    employeeCollection = value;
                    RaisePropertyChanged(() => EmployeeCollection);
                }
            }
        }

        private bool isCreateNew;
        public bool IsCreateNew
        {
            get { return isCreateNew; }
            set
            {
                if (isCreateNew != value)
                {
                    isCreateNew = value;
                    RaisePropertyChanged(() => IsCreateNew);
                }
            }
        }

        private PagedCollectionView materialCollection;
        public PagedCollectionView MaterialCollection
        {
            get { return materialCollection; }
            set
            {
                if (!ReferenceEquals(materialCollection, value))
                {
                    materialCollection = value;
                    RaisePropertyChanged(() => MaterialCollection);
                }
            }
        }

        private PagedCollectionView productCollection;
        public PagedCollectionView ProductCollection
        {
            get { return productCollection; }
            set
            {
                if (!ReferenceEquals(productCollection, value))
                {
                    productCollection = value;
                    RaisePropertyChanged(() => ProductCollection);
                }
            }
        }

        #endregion

        #region Fields

        
        private Warehouse warehouseTemp;

        #endregion

        private void Backup()
        {
            if (Warehouse != null)
            {
                warehouseTemp = new Warehouse()
                {
                    WarehouseID = Warehouse.WarehouseID,
                    WarehouseName = Warehouse.WarehouseName,
                    Address = Warehouse.Address,
                    Description = Warehouse.Description,
                    OfficePhone = Warehouse.OfficePhone,
                    Manager = Warehouse.Manager,
                    MaterialCollection = Warehouse.MaterialCollection,
                    ProductCollection = Warehouse.ProductCollection
                };

            }
        }

        private void MappWithCollection()
        {
            if (!isCreateNew)
            {
                if (Warehouse.Manager != null && EmployeeCollection != null)
                {
                    Employee etempt = EmployeeCollection.FirstOrDefault(manager => manager.EmployeeID == Warehouse.Manager.EmployeeID);
                    if (etempt != null)
                    {
                        Warehouse.Manager = etempt;
                    }
                    else
                    {
                        EmployeeCollection.Add(Warehouse.Manager);
                        Warehouse.Manager = new Employee(){EmployeeID = Warehouse.Manager.EmployeeID};

                        etempt = EmployeeCollection.FirstOrDefault(manager => manager.EmployeeID == Warehouse.Manager.EmployeeID);

                        Warehouse.Manager = etempt;
                    }
                }
            }
        }

        protected override void HandleLoadingCompleted()
        {
            if (ServiceCallCounter == 0 && !isCreateNew && IsFirstLoaded)
            {
                MappWithCollection();
                IsFirstLoaded = false;
            }
        }
    }
}
